package com.example.itcacp.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.example.itcacp.entity.Authority;
import com.example.itcacp.entity.Role;
import com.example.itcacp.entity.RoleAuthority;
import com.example.itcacp.entity.User;
import com.example.itcacp.exception.CustomerException;
import com.example.itcacp.repository.mybatis.AuthorityMapper;
import com.example.itcacp.repository.mybatis.RoleAuthorityMapper;
import com.example.itcacp.repository.mybatis.RoleMapper;
import com.example.itcacp.repository.mybatis.UserMapper;
import com.example.itcacp.service.AdminService;
import com.example.itcacp.util.TokenUtils;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import jakarta.annotation.Resource;
//import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
//import org.springframework.security.crypto.password.PasswordEncoder;
import jakarta.transaction.Transactional;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;

import java.sql.Timestamp;
import java.util.ArrayList;
import java.util.List;

@Service
public class AdminServiceImpl extends ServiceImpl<UserMapper, User> implements AdminService {


    //依赖注入
    @Resource
    private UserMapper userMapper;
    @Resource
    private RoleMapper roleMapper;
    @Resource
    private AuthorityMapper authorityMapper;
    @Resource
    private RoleAuthorityMapper roleAuthorityMapper;

    //登录方法
    @Override
    public User login(User user) {
        //1. 验证账号是否存在，验证角色信息
        User dbadmin = userMapper.selectUserWithRoleByUsername ( user.getUsername () );
        // 密码验证（使用Spring Security的密码匹配器）
        PasswordEncoder encoder = new BCryptPasswordEncoder();
        if (!encoder.matches(user.getPassword(), dbadmin.getPassword())) { // 对比明文和加密密码
            throw new CustomerException("账号或密码错误");
        }
        // 生成JWT（使用固定密钥，载荷包含user_id-role）
        String token = TokenUtils.createToken ( dbadmin.getUser_id () + "-" + dbadmin.getRole ().getRoleName () );
        dbadmin.setToken ( token );
        return dbadmin;
    }

    //新增用户
    @Override
    public void add(User user, String role_name) {
        // 1. 密码加密（使用Spring Security的PasswordEncoder）
        PasswordEncoder encoder = new BCryptPasswordEncoder ();
        String encodedPassword = encoder.encode("123123"); // 初始密码加密
        user.setPassword(encodedPassword);
        // 2. 其余默认项设置
        user.setCreated_at ( new Timestamp ( System.currentTimeMillis () ).toLocalDateTime () );  // 设置创建时间
        user.setProfile_photo_path ( "https://cube.elemecdn.com/3/7c/3ea6beec64369c2642b92c6726f1epng.png" );  // 初始头像
        int userRoleId = userMapper.selectWithByRolename ( role_name ); // 获取前端传递过来的角色数据
        user.setRole_id ( userRoleId ); // 设置角色id
        // 3. 账号和邮箱的唯一性校验
        User dbUser = userMapper.selectByUsernameUser ( user.getUsername () );
        String dbEmail = userMapper.selectByEmail ( user.getEmail () );
        if (dbUser != null) {
            throw new CustomerException ( "昵称已被占用，请更换新的用户昵称" );
        } else if (dbEmail != null) {
            throw new CustomerException ( "邮件已被使用，请更换新的邮件地址" );
        }
        // 4. 插入数据库
        userMapper.insert ( user );
    }

    //删除用户
    @Override
    public void deleteUserById(Long user_id) {
        userMapper.deleteUserById ( user_id );
    }


    //查询全部用户
    @Override
    //@Transactional 涉及到数据库操作的方法都被@Transactional注解修饰，以便Spring能够管理事务（eg：在service实现类方法上加@Transactional注解，使得同步注册）。
    public List<User> selectAll() {
        return userMapper.selectAll ( null, null );
    }

    //分页查询 :所有用户
    @Override
    public PageInfo<User> selectPage(Integer pageNum, Integer pageSize, String name, String rolename) {
        // 开启分页查询
        PageHelper.startPage ( pageNum, pageSize );
        List<User> userList = userMapper.selectAll ( name, rolename );
        return PageInfo.of ( userList );
    }

    // 编辑用户信息
    @Override
    public void update(User user, String role_name) {
        user.setUpdated_at ( new Timestamp ( System.currentTimeMillis () ).toLocalDateTime () );
        int userRoleId = userMapper.selectWithByRolename ( role_name ); // 获取前端传递过来的角色数据
        user.setRole_id ( userRoleId );  // 设置最新的角色id
        userMapper.updateById ( user );
    }

    /**
     * 查询所有角色及对应权限
     * */
    @Override
    public List<Role> selectRoleAll() {
        return roleMapper.selectRoleAll ( null, null );
    }

    //分页查询 :所有角色
    @Override
    public PageInfo<Role> selectRolePage(Integer pageNum, Integer pageSize, String roleName, String authorityName) {
        // 开启分页查询
        PageHelper.startPage ( pageNum, pageSize );
        List<Role> roleList = roleMapper.selectRoleAll ( roleName, authorityName );
        return PageInfo.of ( roleList );
    }

    /**
     * 新增角色：新增角色的同时并为其分配对应权限（在角色权限关联表中添加记录）
     * */
    @Override
    @Transactional
    public void addRole(Role role, List<String> authNames) {
        roleMapper.insert ( role );// 添加角色
        Long roleId = role.getRoleId(); // 获取角色 ID
        addRoleAuthority(roleId, authNames);// 添加角色权限记录
    }
    /**
     * 添加角色的同时添加角色权限记录：it_role_authority
     * */
    private void addRoleAuthority(Long roleId, List<String> authNames) {
        for (String authName : authNames) {
            // 根据权限名称查询权限 ID
            Authority authority = authorityMapper.selectOne(new QueryWrapper<Authority> ().eq("authority_name", authName));
            if (authority != null) {
                Long authorityId = authority.getAuthorityId();
                RoleAuthority roleAuthority = new RoleAuthority ();
                roleAuthority.setRoleId(roleId);
                roleAuthority.setAuthorityId(authorityId);
                roleAuthorityMapper.insert(roleAuthority);
            }
        }
    }

    //删除角色
    @Override
    public void deleteRoleById(Long roleId) {
        roleMapper.deleteById ( roleId );
    }

    // 更新角色
    @Override
    public void updateRole(Role role, List<String> authNames) {
        roleMapper.updateById ( role ); // 更新角色
        Long roleId = role.getRoleId(); // 获取角色 ID
        updateRoleAuthority(roleId, authNames);// 添加角色权限记录
    }
    // 更新角色权限记录
    private void updateRoleAuthority(Long roleId, List<String> authNames) {
        // 先删除该角色现有的所有权限记录
        QueryWrapper<RoleAuthority> wrapper = new QueryWrapper<>();
        wrapper.eq("role_id", roleId);
        roleAuthorityMapper.delete(wrapper);
        // 查找权限，如果不存在则添加
        List<RoleAuthority> roleAuthorities = new ArrayList<> ();
        for (String authName : authNames) {
            QueryWrapper<Authority> authWrapper = new QueryWrapper<>();
            authWrapper.eq("authority_name", authName);
            Authority authority = authorityMapper.selectOne(authWrapper);
            if (authority == null) {
                authority = new Authority();
                authority.setAuthorityName(authName);
                authorityMapper.insert(authority);
            }
            // 创建新的角色权限关联记录
            RoleAuthority roleAuthority = new RoleAuthority();
            roleAuthority.setRoleId(roleId);
            roleAuthority.setAuthorityId(authority.getAuthorityId());
            roleAuthorities.add(roleAuthority);
        }
        // 批量插入新的角色权限记录
        if (!roleAuthorities.isEmpty()) {
            roleAuthorityMapper.insertBatch ( roleAuthorities );
        }
    }


    /**
     * 查询所有权限
     * */
    @Override
    public List<Authority> selectAuthAll() {
        return authorityMapper.selectAuthAll ( null );
    }

    /**
     *
     * 分页查询 :所有角色
     */
    @Override
    public PageInfo<Authority> selectAuthPage(Integer pageNum, Integer pageSize, String authorityName) {
        // 开启分页查询
        PageHelper.startPage ( pageNum, pageSize );
        List<Authority> authList = authorityMapper.selectAuthAll ( authorityName );
        return PageInfo.of ( authList );
    }

    /**
     *添加权限
     */
    @Override
   public void addAuth(Authority authority) {
        authorityMapper.insert ( authority );
    }
    /**
     *删除权限
     */
    @Override
   public void deleteAuthById(Long authorityId) {
        authorityMapper.deleteById ( authorityId );
    }
    /**
     *更新权限
     */
    @Override
   public void updateAuth(Authority authority) {
        authorityMapper.updateById ( authority );
    }
}